package com.csg.boot.starter.sso.config;

import com.csg.boot.starter.sso.constant.SsoProperties;
import com.csg.boot.starter.sso.context.InitParameterInitializer;
import com.sgcc.isc.ualogin.client.filter.*;
import com.sgcc.isc.ualogin.client.listener.IscSingleSignOutHttpSessionListener;
import com.sgcc.isc.ualogin.client.servlet.IscFederationServlet;
import com.sgcc.isc.ualogin.client.servlet.IscSingleSignOutServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * @author george
 */
@Configuration
public class SsoConfig {

    private static final String SERVER_LOGIN_URL = "/login";

    private static final String SERVER_LOGOUT_URL = "/logout";

    private static final String SERVER_NAME = "serverName";

    @Autowired
    private SsoProperties properties;

    @Bean
    public InitParameterInitializer initParameter() {
        Map<String, String> contextParams = new HashMap<>(2);
        contextParams.put("ssoServerUrl", properties.getServerUrlPrefix());
        contextParams.put("appid", properties.getAppId());
        return new InitParameterInitializer(contextParams);
    }

    /**
     * 用户会话监听器
     *
     * @return
     */
    @Bean
    public ServletListenerRegistrationBean<IscSingleSignOutHttpSessionListener> ssoHttpSessionListener() {
        return new ServletListenerRegistrationBean<>(new IscSingleSignOutHttpSessionListener());
    }

    /**
     * @return
     */
    @Bean
    public FilterRegistrationBean ssoFilter() {
        FilterRegistrationBean<IscSingleSignOutFilter> bean = new FilterRegistrationBean<>(new IscSingleSignOutFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }

    /**
     * 用户登陆状态检测
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean authenticationFilter() {
        FilterRegistrationBean<IscSSOAuthenticationFilter> bean = new FilterRegistrationBean<>(new IscSSOAuthenticationFilter());
        bean.addInitParameter("serverLoginUrl", properties.getServerUrlPrefix() + SERVER_LOGIN_URL);
        bean.addInitParameter(SERVER_NAME, properties.getServiceName());
        bean.addUrlPatterns("/*");
        return bean;
    }

    /**
     * 用户登陆票有效性检测
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean validationFilter() {
        FilterRegistrationBean<IscSSO20ProxyReceivingTicketValidationFilter> bean = new FilterRegistrationBean<>(new IscSSO20ProxyReceivingTicketValidationFilter());
        bean.addInitParameter("serverUrlPrefix", properties.getServerUrlPrefix());
        bean.addInitParameter(SERVER_NAME, properties.getServiceName());
        bean.addInitParameter("encoding", "utf-8");
        bean.addUrlPatterns("/*");
        return bean;
    }

    /**
     * @return
     */
    @Bean
    public FilterRegistrationBean httpServletRequestWrapperFilter() {
        FilterRegistrationBean<IscSSOHttpServletRequestWrapperFilter> bean = new FilterRegistrationBean<>(new IscSSOHttpServletRequestWrapperFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }

    /**
     * @return
     */
    @Bean
    public FilterRegistrationBean assertionThreadLocalFilter() {
        FilterRegistrationBean<IsoSSOAssertionThreadLocalFilter> bean = new FilterRegistrationBean<>(new IsoSSOAssertionThreadLocalFilter());
        bean.addUrlPatterns("/*");
        return bean;
    }

    /**
     * 单点登出Servlet配置
     *
     * @return
     */
    @Bean
    public ServletRegistrationBean ssoServlet() {
        ServletRegistrationBean<IscSingleSignOutServlet> bean = new ServletRegistrationBean<>(new IscSingleSignOutServlet());
        bean.addInitParameter("serverLogoutUrl", properties.getServerUrlPrefix() + SERVER_LOGOUT_URL);
        bean.addInitParameter(SERVER_NAME, properties.getServiceName());
        bean.addUrlMappings("/signout");
        return bean;
    }

    /**
     * 应用级联认证支持（可选）
     *
     * @return
     */
    @Bean
    public ServletRegistrationBean federationServlet() {
        ServletRegistrationBean<IscFederationServlet> bean = new ServletRegistrationBean<>(new IscFederationServlet());
        bean.addUrlMappings("/federation");
        return bean;
    }

}
